package com.ruoyi.system.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.system.domain.*;
import com.ruoyi.system.mapper.*;
import com.ruoyi.system.service.IGrainsituationRecordDetailService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 粮情主下的详情Service业务层处理
 *
 * @author ruoyi
 * @date 2025-04-03
 */
@Service
public class GrainsituationRecordDetailServiceImpl extends ServiceImpl<GrainsituationRecordDetailMapper, GrainsituationRecordDetail> implements IGrainsituationRecordDetailService {
    @Autowired
    private GrainsituationRecordDetailMapper grainsituationRecordDetailMapper;
    @Autowired
    private GrainsituationWarehouseTempositionMapper grainsituationWarehouseTempositionMapper;
    @Autowired
    private GrainsituationRecordMapper grainsituationRecordMapper;
    @Autowired
    private IotCubeLcMapper iotCubeLcMapper;
    @Autowired
    private IotCubeLcCableMapper iotCubeLcCableMapper;

    /**
     * 查询粮情主下的详情
     *
     * @param id 粮情主下的详情主键
     * @return 粮情主下的详情
     */
    @Override
    public GrainsituationRecordDetail selectGrainsituationRecordDetailById(Long id) {
        return this.getById(id);
    }

    /**
     * 查询粮情主下的详情列表
     * 
     * @param grainsituationRecordDetail 粮情主下的详情
     * @return 粮情主下的详情
     */
    @Override
    public List<GrainsituationRecordDetail> selectGrainsituationRecordDetailList(GrainsituationRecordDetail grainsituationRecordDetail)
    {
        return grainsituationRecordDetailMapper.selectGrainsituationRecordDetailList(grainsituationRecordDetail);
    }

    /**
     * 新增粮情主下的详情
     * 
     * @param grainsituationRecordDetail 粮情主下的详情
     * @return 结果
     */
    @Override
    public boolean insertGrainsituationRecordDetail(GrainsituationRecordDetail grainsituationRecordDetail)
    {
        return this.save(grainsituationRecordDetail);
    }

    /**
     * 修改粮情主下的详情
     * 
     * @param grainsituationRecordDetail 粮情主下的详情
     * @return 结果
     */
    @Override
    public boolean updateGrainsituationRecordDetail(GrainsituationRecordDetail grainsituationRecordDetail)
    {
        return this.updateById(grainsituationRecordDetail);
    }

    /**
     * 批量删除粮情主下的详情
     * 
     * @param ids 需要删除的粮情主下的详情主键
     * @return 结果
     */
    @Override
    public boolean deleteGrainsituationRecordDetailByIds(Long[] ids)
    {
        return super.removeByIds(Arrays.asList(ids));
    }

    /**
     * 删除粮情主下的详情信息
     *
     * @param id 粮情主下的详情主键
     * @return 结果
     */
    @Override
    public boolean deleteGrainsituationRecordDetailById(Long id) {
        return this.removeById(id);
    }

    @Override
    public SectorDTO getRecordDetailList(GrainsituationRecordDetail grainsituationRecordDetail) {
        //先取仓房xyz配置
        GrainsituationWarehouseTemposition grainsituationWarehouseTemposition = grainsituationWarehouseTempositionMapper.selectOne(new LambdaQueryWrapper<GrainsituationWarehouseTemposition>()
                .eq(GrainsituationWarehouseTemposition::getWarehouseId, grainsituationRecordDetail.getWarehouseId()));
        Integer warehouseXnum = grainsituationWarehouseTemposition.getWarehouseXnum();
        Integer warehouseYnum = grainsituationWarehouseTemposition.getWarehouseYnum();
        Integer warehouseZnum = grainsituationWarehouseTemposition.getWarehouseZnum();
        //获取当前仓房下所有数据
        GrainsituationRecord grainsituationRecord = grainsituationRecordMapper.selectOne(new LambdaQueryWrapper<GrainsituationRecord>()
                .eq(GrainsituationRecord::getWarehouseId, grainsituationRecordDetail.getWarehouseId())
                .eq(grainsituationRecordDetail.getDetectionTime() != null, GrainsituationRecord::getDetectionTime, grainsituationRecordDetail.getDetectionTime())
                .orderByDesc(GrainsituationRecord::getDetectionTime)
                .last("limit 1"));
        List<GrainsituationRecordDetail> allRecordList = this.list(new LambdaQueryWrapper<GrainsituationRecordDetail>().eq(GrainsituationRecordDetail::getRecordID, grainsituationRecord.getId()));
        SectorDTO sectorDTO = new SectorDTO();
        LinkedList<LinkedList<TemperatureDataListDTO>> lastData = new LinkedList<>();

        LinkedList<LinkedList<BigDecimal>> zData = new LinkedList<>();
        for (int i = 0; i < warehouseZnum; i++) {
            LinkedList<BigDecimal> bigDecimals = new LinkedList<>();
            zData.add(bigDecimals);
        }
        //第一行数据
        for (Integer i = 0; i < warehouseYnum; i++) {
            getFoodData(warehouseXnum, warehouseZnum, i, allRecordList, lastData, zData);
        }
        sectorDTO.setData(lastData);
        //中间的统计
        sectorDTO.setMaxTemValue(grainsituationRecord.getMaxTemValue());
        sectorDTO.setMinTemValue(grainsituationRecord.getMinTemValue());
        sectorDTO.setAvgTemValue(grainsituationRecord.getAvgTemValue());

        CommonCountDTO commonCountDTO = new CommonCountDTO();
        commonCountDTO.setInTemValue(grainsituationRecord.getInTemValue());
        commonCountDTO.setInHumValue(grainsituationRecord.getInHumValue());
        commonCountDTO.setOutHumValue(grainsituationRecord.getOutHumValue());
        commonCountDTO.setOutTemValue(grainsituationRecord.getOutTemValue());
        commonCountDTO.setMax(grainsituationRecord.getMaxTemValue() == null ? "" : grainsituationRecord.getMaxTemValue().toPlainString());
        commonCountDTO.setMin(grainsituationRecord.getMinTemValue() == null ? "" : grainsituationRecord.getMinTemValue().toPlainString());
        commonCountDTO.setAgv(grainsituationRecord.getAvgTemValue() == null ? "" : grainsituationRecord.getAvgTemValue().toPlainString());

        List<CountDTO> countList = new ArrayList<>();
        for (int i = 0; i < zData.size(); i++) {
            LinkedList<BigDecimal> list = zData.get(i);

            CountDTO countDTO = new CountDTO();
            countDTO.setNo(i+1);
            countDTO.setMax(list.stream().max(Comparator.comparing(BigDecimal::doubleValue)).orElse(BigDecimal.ZERO).toPlainString());
            countDTO.setMin(list.stream().min(Comparator.comparing(BigDecimal::doubleValue)).orElse(BigDecimal.ZERO).toPlainString());
            countDTO.setAgv(list.stream().reduce(BigDecimal.ZERO, BigDecimal::add).divide(new BigDecimal(list.size()), 2, RoundingMode.HALF_UP).toPlainString());
            countList.add(countDTO);
        }

        commonCountDTO.setCountList(countList);
        sectorDTO.setCommonCountDTO(commonCountDTO);

        //墙面数据
        List<IotCubeLc> iotCubeLcs = iotCubeLcMapper.selectList(new LambdaQueryWrapper<IotCubeLc>()
                .eq(IotCubeLc::getWarehouseId, grainsituationRecordDetail.getWarehouseId()));
        List<Long> lcIds = iotCubeLcs.stream().map(IotCubeLc::getId).collect(Collectors.toList());
        if (CollectionUtil.isNotEmpty(lcIds)) {
            List<IotCubeLcCable> iotCubeLcCables = iotCubeLcCableMapper.selectList(new LambdaQueryWrapper<IotCubeLcCable>().in(IotCubeLcCable::getLcId, lcIds));
            if (CollectionUtil.isNotEmpty(iotCubeLcCables)) {
                //北墙 lcId为2
                List<TemperatureDataListDTO> north = new ArrayList<>();
                List<IotCubeLcCable> northList = iotCubeLcCables.stream().filter(iotCubeLcCable -> iotCubeLcCable.getLcId() == 2L).collect(Collectors.toList());
                IotCubeLcCable nCable6 = northList.stream().filter(iotCubeLcCable -> iotCubeLcCable.getCableCode().equals("cable6")).findFirst().orElse(null);
                markWallData(north, nCable6);
                IotCubeLcCable nCable5 = northList.stream().filter(iotCubeLcCable -> iotCubeLcCable.getCableCode().equals("cable5")).findFirst().orElse(null);
                markWallData(north, nCable5);
                IotCubeLcCable nCable4 = northList.stream().filter(iotCubeLcCable -> iotCubeLcCable.getCableCode().equals("cable4")).findFirst().orElse(null);
                markWallData(north, nCable4);
                IotCubeLcCable nCable3 = northList.stream().filter(iotCubeLcCable -> iotCubeLcCable.getCableCode().equals("cable3")).findFirst().orElse(null);
                markWallData(north, nCable3);
                sectorDTO.setNorth(north);

                //南墙 lcId为1
                List<TemperatureDataListDTO> south = new ArrayList<>();
                List<IotCubeLcCable> southList = iotCubeLcCables.stream().filter(iotCubeLcCable -> iotCubeLcCable.getLcId() == 1L).collect(Collectors.toList());
                IotCubeLcCable sCable3 = southList.stream().filter(iotCubeLcCable -> iotCubeLcCable.getCableCode().equals("cable3")).findFirst().orElse(null);
                markWallData(south, sCable3);
                IotCubeLcCable sCable4 = southList.stream().filter(iotCubeLcCable -> iotCubeLcCable.getCableCode().equals("cable4")).findFirst().orElse(null);
                markWallData(south, sCable4);
                IotCubeLcCable sCable5 = southList.stream().filter(iotCubeLcCable -> iotCubeLcCable.getCableCode().equals("cable5")).findFirst().orElse(null);
                markWallData(south, sCable5);
                IotCubeLcCable sCable6 = southList.stream().filter(iotCubeLcCable -> iotCubeLcCable.getCableCode().equals("cable6")).findFirst().orElse(null);
                markWallData(south, sCable6);
                sectorDTO.setSouth(south);

                //西
                List<TemperatureDataListDTO> west = new ArrayList<>();
                IotCubeLcCable wCable7 = northList.stream().filter(iotCubeLcCable -> iotCubeLcCable.getCableCode().equals("cable7")).findFirst().orElse(null);
                markWallData(west, wCable7);
                IotCubeLcCable wCable8 = northList.stream().filter(iotCubeLcCable -> iotCubeLcCable.getCableCode().equals("cable8")).findFirst().orElse(null);
                markWallData(west, wCable8);
                IotCubeLcCable wCable1 = southList.stream().filter(iotCubeLcCable -> iotCubeLcCable.getCableCode().equals("cable1")).findFirst().orElse(null);
                markWallData(west, wCable1);
                IotCubeLcCable wCable2 = southList.stream().filter(iotCubeLcCable -> iotCubeLcCable.getCableCode().equals("cable2")).findFirst().orElse(null);
                markWallData(west, wCable2);
                sectorDTO.setWest(west);

                //西
                List<TemperatureDataListDTO> east = new ArrayList<>();
                IotCubeLcCable eCable2 = northList.stream().filter(iotCubeLcCable -> iotCubeLcCable.getCableCode().equals("cable2")).findFirst().orElse(null);
                markWallData(east, eCable2);
                IotCubeLcCable eCable1 = northList.stream().filter(iotCubeLcCable -> iotCubeLcCable.getCableCode().equals("cable1")).findFirst().orElse(null);
                markWallData(east, eCable1);
                IotCubeLcCable eCable8 = southList.stream().filter(iotCubeLcCable -> iotCubeLcCable.getCableCode().equals("cable8")).findFirst().orElse(null);
                markWallData(east, eCable8);
                IotCubeLcCable eCable7 = southList.stream().filter(iotCubeLcCable -> iotCubeLcCable.getCableCode().equals("cable7")).findFirst().orElse(null);
                markWallData(east, eCable7);
                sectorDTO.setEast(east);
                //中间统计

                //地面
                List<String> groundList = Arrays.asList("cable1", "cable2", "cable3", "cable4", "cable5", "cable6", "cable7", "cable8", "cable11", "cable12", "cable13", "cable14", "cable15", "cable16", "cable17", "cable18");
                List<IotCubeLcCable> up = northList.stream().filter(iotCubeLcCable -> groundList.contains(iotCubeLcCable.getCableCode())).collect(Collectors.toList());
                List<TemperatureDataListDTO> groundUp = up.stream().map(iotCubeLcCable -> {
                    TemperatureDataListDTO temperatureDataListDTO = getTemperatureDataListDTO(iotCubeLcCable);
                    return temperatureDataListDTO;
                }).collect(Collectors.toList());
                sectorDTO.setGroundUp(groundUp);
                List<IotCubeLcCable> down = southList.stream().filter(iotCubeLcCable -> groundList.contains(iotCubeLcCable.getCableCode())).collect(Collectors.toList());
                List<TemperatureDataListDTO> groundDown = down.stream().map(iotCubeLcCable -> {
                    TemperatureDataListDTO temperatureDataListDTO = getTemperatureDataListDTO(iotCubeLcCable);
                    return temperatureDataListDTO;
                }).collect(Collectors.toList());
                sectorDTO.setGroundDown(groundDown);
            }
        }
        return sectorDTO;
    }

    private void markWallData(List<TemperatureDataListDTO> north, IotCubeLcCable iotCubeLcCable) {
        if (iotCubeLcCable == null) {
            return;
        }
        TemperatureDataListDTO temperatureDataListDTO = getTemperatureDataListDTO(iotCubeLcCable);

        north.add(temperatureDataListDTO);
    }

    private static TemperatureDataListDTO getTemperatureDataListDTO(IotCubeLcCable iotCubeLcCable) {
        TemperatureDataListDTO temperatureDataListDTO = new TemperatureDataListDTO();
        temperatureDataListDTO.setTopNo(Integer.parseInt(iotCubeLcCable.getCableCode().replaceAll("[^0-9]", "")));
        LinkedList<String> dataList = new LinkedList<>();
        dataList.add(iotCubeLcCable.getDataPoint1() == null ? "" : iotCubeLcCable.getDataPoint1().toPlainString());
        dataList.add(iotCubeLcCable.getDataPoint2() == null ? "" : iotCubeLcCable.getDataPoint2().toPlainString());
        dataList.add(iotCubeLcCable.getDataPoint3() == null ? "" : iotCubeLcCable.getDataPoint3().toPlainString());
        dataList.add(iotCubeLcCable.getDataPoint4() == null ? "" : iotCubeLcCable.getDataPoint4().toPlainString());
        temperatureDataListDTO.setData(dataList);
        return temperatureDataListDTO;
    }

    private static void getFoodData(Integer warehouseXnum, Integer warehouseZnum, Integer ynum, List<GrainsituationRecordDetail> allRecordList, LinkedList<LinkedList<TemperatureDataListDTO>> lastData, LinkedList<LinkedList<BigDecimal>> zData) {
        List<GrainsituationRecordDetail> collect = allRecordList.stream().filter(d -> d.getYnum().equals(ynum)).sorted(Comparator.comparing(GrainsituationRecordDetail::getXnum).thenComparing(GrainsituationRecordDetail::getZnum)).collect(Collectors.toList());

        LinkedList<TemperatureDataListDTO> data1 = new LinkedList<>();
        for (int i = 0; i < warehouseXnum; i++) {
            int finalI = i;
            List<GrainsituationRecordDetail> collect1 = collect.stream().filter(d -> d.getXnum() == finalI).collect(Collectors.toList());
            TemperatureDataListDTO temperatureDataListDTO = new TemperatureDataListDTO();
            temperatureDataListDTO.setTopNo(i + 1);
            LinkedList<String> data = new LinkedList<>();
            for (int j = warehouseZnum - 1; j >= 0; j--) {
                LinkedList<BigDecimal> bigDecimals = zData.get(j);
                bigDecimals.add(collect1.get(j).getTemValue());
                data.add(collect1.get(j).getTemValue().toString());
            }
            temperatureDataListDTO.setData(data);
            data1.add(temperatureDataListDTO);
        }
        lastData.add(data1);
    }
}
